home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-04-19 | 8.5 KB | 238 lines | [TEXT/MOSS] |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1999 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s): Stephen Lamm <slamm@netscape.com>
- */
-
- /*
- * No magic constructor behaviour, as is de rigeur for XPCOM.
- * If you must perform some initialization, and it could possibly fail (even
- * due to an out-of-memory condition), you should use an Init method, which
- * can convey failure appropriately (thrown exception in JS,
- * NS_FAILED(nsresult) return in C++).
- *
- * In JS, you can actually cheat, because a thrown exception will cause the
- * CreateInstance call to fail in turn, but not all languages are so lucky.
- * (Though ANSI C++ provides exceptions, they are verboten in Mozilla code
- * for portability reasons -- and even when you're building completely
- * platform-specific code, you can't throw across an XPCOM method boundary.)
- */
-
- const DEBUG = true; /* set to false to suppress debug messages */
- const PANELS_RDF_FILE = 66626; /* the magic number to find panels.rdf */
-
- const SIDEBAR_PROGID = "component://mozilla/sidebar";
- const SIDEBAR_CID = Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}");
- const CONTAINER_PROGID = "component://netscape/rdf/container";
- const LOCATOR_PROGID = "component://netscape/filelocator";
- const nsISupports = Components.interfaces.nsISupports;
- const nsIFactory = Components.interfaces.nsIFactory;
- const nsISidebar = Components.interfaces.nsISidebar;
- const nsIRDFContainer = Components.interfaces.nsIRDFContainer;
- const nsIFileLocator = Components.interfaces.nsIFileLocator;
- const nsIRDFRemoteDataSource = Components.interfaces.nsIRDFRemoteDataSource;
-
- function nsSidebar()
- {
- const RDF_PROGID = "component://netscape/rdf/rdf-service";
- const nsIRDFService = Components.interfaces.nsIRDFService;
-
- this.rdf = Components.classes[RDF_PROGID].getService(nsIRDFService);
- this.datasource_uri = getSidebarDatasourceURI(PANELS_RDF_FILE);
- debug('datasource_uri is ' + this.datasource_uri);
- this.resource = 'urn:sidebar:current-panel-list';
- this.datasource = this.rdf.GetDataSource(this.datasource_uri);
- }
-
- nsSidebar.prototype.nc = "http://home.netscape.com/NC-rdf#";
-
- nsSidebar.prototype.setWindow =
- function (aWindow)
- {
- this.window = aWindow;
- }
-
- nsSidebar.prototype.isPanel =
- function (aContentURL)
- {
- var container =
- Components.classes[CONTAINER_PROGID].createInstance(nsIRDFContainer);
-
- container.Init(this.datasource, this.rdf.GetResource(this.resource));
-
- /* Create a resource for the new panel and add it to the list */
- var panel_resource =
- this.rdf.GetResource("urn:sidebar:3rdparty-panel:" + aContentURL);
-
- return (container.IndexOf(panel_resource) != -1);
- }
-
-
- /* decorate prototype to provide ``class'' methods and property accessors */
- nsSidebar.prototype.addPanel =
- function (aTitle, aContentURL, aCustomizeURL)
- {
- debug("addPanel(" + aTitle + ", " + aContentURL + ", " +
- aCustomizeURL + ")");
-
- if (!this.window)
- {
- debug ("no window object set, bailing out.");
- throw Components.results.NS_ERROR_NOT_INITIALIZED;
- }
-
- /* Create a "container" wrapper around the
- * "urn:sidebar:current-panel-list" object. This makes it easier
- * to manipulate the RDF:Seq correctly. */
- var container =
- Components.classes[CONTAINER_PROGID].createInstance(nsIRDFContainer);
- container.Init(this.datasource, this.rdf.GetResource(this.resource));
-
- /* Create a resource for the new panel and add it to the list */
- var panel_resource =
- this.rdf.GetResource("urn:sidebar:3rdparty-panel:" + aContentURL);
- var panel_index = container.IndexOf(panel_resource);
- if (panel_index != -1)
- {
- this.window.alert(aContentURL + " already exists in your sidebar.");
- return;
- }
-
- var rv = this.window.confirm("Add " + aContentURL + " to your sidebar?");
- if (!rv)
- return;
-
- this.datasource.Assert(this.rdf.GetResource(this.resource),
- this.rdf.GetResource(this.nc + "inbatch"),
- this.rdf.GetLiteral("true"),
- true);
-
- /* Now make some sidebar-ish assertions about it... */
- this.datasource.Assert(panel_resource,
- this.rdf.GetResource(this.nc + "title"),
- this.rdf.GetLiteral(aTitle),
- true);
- this.datasource.Assert(panel_resource,
- this.rdf.GetResource(this.nc + "content"),
- this.rdf.GetLiteral(aContentURL),
- true);
- if (aCustomizeURL)
- this.datasource.Assert(panel_resource,
- this.rdf.GetResource(this.nc + "customize"),
- this.rdf.GetLiteral(aCustomizeURL),
- true);
-
- container.AppendElement(panel_resource);
-
- this.datasource.Unassert(this.rdf.GetResource(this.resource),
- this.rdf.GetResource(this.nc + "inbatch"),
- this.rdf.GetLiteral("true"));
-
- /* Write the modified panels out. */
- this.datasource.QueryInterface(nsIRDFRemoteDataSource).Flush();
-
- }
-
- var sidebarModule = new Object();
-
- sidebarModule.registerSelf =
- function (compMgr, fileSpec, location, type)
- {
- debug("registering (all right -- a JavaScript module!)");
- compMgr.registerComponentWithType(SIDEBAR_CID, "Sidebar JS Component",
- SIDEBAR_PROGID, fileSpec, location,
- true, true, type);
- }
-
- sidebarModule.getClassObject =
- function (compMgr, cid, iid) {
- if (!cid.equals(SIDEBAR_CID))
- throw Components.results.NS_ERROR_NO_INTERFACE;
-
- if (!iid.equals(Components.interfaces.nsIFactory))
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
- return sidebarFactory;
- }
-
- sidebarModule.canUnload =
- function(compMgr)
- {
- debug("Unloading component.");
- return true;
- }
-
- /* factory object */
- sidebarFactory = new Object();
-
- sidebarFactory.CreateInstance =
- function (outer, iid) {
- debug("CI: " + iid);
- if (outer != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- if (!iid.equals(nsISidebar) && !iid.equals(nsISupports))
- throw Components.results.NS_ERROR_INVALID_ARG;
-
- return new nsSidebar();
- }
-
- /* entrypoint */
- function NSGetModule(compMgr, fileSpec) {
- return sidebarModule;
- }
-
- /* static functions */
- if (DEBUG)
- debug = function (s) { dump("-*- sidebar: " + s + "\n"); }
- else
- debug = function (s) {}
-
- function getSidebarDatasourceURI(panels_file_id)
- {
- try
- {
- /* use the fileLocator to look in the profile directory
- * to find 'panels.rdf', which is the
- * database of the user's currently selected panels. */
- var fileLocatorService =
- Components.classes[LOCATOR_PROGID].getService(nsIFileLocator);
-
- /* if <profile>/panels.rdf doesn't exist, GetFileLocation() will copy
- *bin/defaults/profile/panels.rdf to <profile>/panels.rdf */
- var sidebar_file = fileLocatorService.GetFileLocation(panels_file_id);
-
- if (!sidebar_file.exists())
- {
- /* this should not happen, as GetFileLocation() should copy
- * defaults/panels.rdf to the users profile directory */
- debug("sidebar file does not exist");
- return null;
- }
-
- debug("sidebar uri is " + sidebar_file.URLString);
- return sidebar_file.URLString;
- }
- catch (ex)
- {
- /* this should not happen */
- debug("caught " + ex + " getting sidebar datasource uri");
- return null;
- }
- }
-